package com.dragon.mapper;

import com.dragon.pojo.Problem.ProblemList;
import com.dragon.pojo.Record.Record;
import com.dragon.pojo.Record.RecordInfo;
import com.dragon.pojo.User.UserBaseInfo;
import com.dragon.pojo.contest.Contest;
import com.dragon.pojo.contest.ContestInfo;
import com.dragon.pojo.contest.ContestList;
import com.dragon.pojo.contest.ContestRecordTemp;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.time.LocalDateTime;
import java.util.List;

@Mapper
public interface ContestMapper {

    @Select("SELECT id, contest_name, type, start_time, end_time, problemTotal, creator from contest order by start_time limit #{offset}, #{listNumber} ")
    List<ContestList> GetContestList(Integer offset, Integer listNumber);

    @Select("SELECT count(*) from contest")
    Integer getContestTotal();

    @Select("SELECT type from contest where id=#{contestId}")
    Integer getContestType(Integer contestId);

    @Select("SELECT id, contest_name, description, type, start_time, end_time, problemTotal, creator, create_time, update_time from contest where id=#{contestId}")
    Contest getContestInfo(Integer contestId);

    @Select("SELECT count(*) from contest_user where user_id=#{userId} and contest_id=#{contestId}")
    Integer getIsInvited(Integer contestId, Integer userId);

    @Select("select p.id,title_name,algorithm_tag,difficulty, max(cs.score) as complete_status " +
            "from problem p join contest_problem cp on p.id = cp.problem_id and cp.contest_id=#{contestId} " +
            "left join contest_submission cs on p.id = cs.problem_id AND cs.user_id=#{userId} AND cs.contest_id = #{contestId} " +
            "GROUP BY p.id, title_name, algorithm_tag, difficulty, cp.`order` order by cp.`order`")
    List<ProblemList> getContestProblemList(Integer contestId, Integer userId);

    void addContest(ContestInfo info);

    void addContestProblem(List<Integer> problemIdList, Integer contestId);

    void addContestUser(List<Integer> userIdList, Integer contestId);

    @Delete("DELETE FROM contest where id=#{contestId}")
    void deleteContest(Integer contestId);

    @Delete("DELETE FROM contest_problem where contest_id=#{contestId}")
    void deleteContestProblem(Integer contestId);

    @Delete("DELETE FROM contest_user where contest_id=#{contestId}")
    void deleteContestUser(Integer contestId);

    @Update("UPDATE contest set contest_name=#{contestName},description=#{description},type=#{type},start_time=#{startTime},end_time=#{endTime},problemTotal=#{problemTotal},update_time=now() where id=#{contestId}")
    void updateContest(ContestInfo info);


    void addRecord(Record record);

    @Select("SELECT username FROM contest_submission where contest_id=#{contestId} group by username")
    List<String> getContestRecordUsername(Integer contestId);

    @Select("SELECT start_time from contest where id=#{contestId}")
    LocalDateTime getContestStartTime(Integer contestId);

    @Select("SELECT MAX(score) as score,MIN(create_time) as ac_time,`order` from contest_submission cs join online_judge.contest_problem cp on cs.contest_id = cp.contest_id and cs.problem_id = cp.problem_id and cp.contest_id=#{contestId} where username=#{username} group by `order`")
    List<ContestRecordTemp> getContestSubInfo(Integer contestId, String username);

    @Select("SELECT problemTotal FROM contest where id=#{contestId}")
    Integer getContestProblemTotal(Integer contestId);

    @Select("SELECT count(distinct username) as select_total from contest_submission")
    Integer getContestantTotal(Integer contestId);

    @Select("SELECT problem_id, user_id, problem_title, cs.username, avatar, complete_status, score, time, memory, file_size, language," +
            "code_path, point_list, cs.create_time, cs.update_time from contest_submission cs left join online_judge.user u on u.id = cs.user_id where cs.id=#{recordId}")
    @org.apache.ibatis.annotations.Results({
            @org.apache.ibatis.annotations.Result(property = "pointList", column = "point_list", typeHandler = com.dragon.Handler.custom.JudgeInfoListTypeHandler.class)
    })
    RecordInfo getContestRecordInfo(Integer recordId);

    @Select("SELECT u.id, username, permissions, nickname, avatar from contest_user cu join online_judge.user u on u.id = cu.user_id where contest_id=#{contestId}")
    List<UserBaseInfo> getUserBaseInfoByContestId(Integer contestId);
}
